package com.happyhome.controller;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.imageio.ImageIO;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.imgscalr.Scalr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import com.happyhome.constants.AppConstant;
import com.happyhome.datamodel.Image;
import com.happyhome.services.ImageService;

@Controller
@RequestMapping("/admin/images")
public class ImagesController {
	
	private static final Logger log = LoggerFactory.getLogger(ImagesController.class);
	
	@Autowired
	private ImageService imageService;
	
	@Autowired
	private ServletContext context;
	
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public ModelAndView login() {
		return new ModelAndView("/admin/images/list");
	}
	
	@RequestMapping(value = "/getDataImages", method = RequestMethod.GET)
	public @ResponseBody List<Image> getDataImages() {
		List<Image> listImages = imageService.getAllImagesFree();
	    return listImages;
	}
	
 	/**
 	 * upload image for room
 	 * @param houseId
 	 * @return
 	 */
 	/* get method upload house's image */
	@RequestMapping(value = "/uploadImages", method = RequestMethod.GET, produces="text/html; charset=utf-8")
	public ModelAndView uploadImages() {
		ModelAndView model = new ModelAndView("admin/images/uploadImages");
		
		List<Image> images = imageService.getAllImagesFree();
		
		if(images != null && images.size() > 0){
			for(Image image: images){
				image.setUrl("/" + AppConstant.APP_URL + "/admin/images/picture/" + image.getId());
	            image.setThumbnailUrl("/" + AppConstant.APP_URL + "/admin/images/thumbnail/" + image.getId());
	            image.setDeleteUrl("/" + AppConstant.APP_URL + "/admin/images/delete/" + image.getId());
	            image.setDeleteType("DELETE");
			}
		}
		model.addObject("images", images);
		return model;
	}
	
	@RequestMapping(value = "/uploadImages", method = RequestMethod.POST)
    public @ResponseBody Map<String, Object> upload(MultipartHttpServletRequest request, HttpServletResponse response) {
        Iterator<String> itr = request.getFileNames();
        MultipartFile mpf;
        List<Image> list = new LinkedList<Image>();
        while (itr.hasNext()) {
            mpf = request.getFile(itr.next());
            
            String newFilenameBase = UUID.randomUUID().toString();
            String originalFileExtension = mpf.getOriginalFilename().substring(mpf.getOriginalFilename().lastIndexOf("."));
            String newFilename = newFilenameBase + originalFileExtension;
            
            String filename = "/WEB-INF" ;
			String pathname = context.getRealPath(filename);
			
			File dir = new File(pathname + File.separator + "images");
			
			if(!dir.exists()){
				dir.mkdirs();
			}
			
            String contentType = mpf.getContentType();
            
            File newFile = new File(dir.getAbsolutePath() + File.separator + newFilename);
            try {
                mpf.transferTo(newFile);
                
                BufferedImage thumbnail = Scalr.resize(ImageIO.read(newFile), 80);
                String thumbnailFilename = newFilenameBase + "-thumbnail.png";
                File thumbnailFile = new File(dir.getAbsolutePath() + File.separator + thumbnailFilename);
                ImageIO.write(thumbnail, "png", thumbnailFile);
                
                Image image = new Image();
                image.setName(mpf.getOriginalFilename());
                image.setThumbnailFilename(thumbnailFilename);
                image.setNewFilename(newFilename);
                image.setContentType(contentType);
                image.setSize(mpf.getSize());
                image.setThumbnailSize(thumbnailFile.length());
                image.setDateCreated(new Date());
                image.setLastUpdated(new Date());
                image = imageService.merge(image);
                
                image.setUrl("/" + AppConstant.APP_URL + "/admin/images/picture/"+ image.getId());
                image.setThumbnailUrl("/" + AppConstant.APP_URL + "/admin/images/thumbnail/"+ image.getId());
                image.setDeleteUrl("/" + AppConstant.APP_URL + "/admin/images/delete/"+ image.getId());
                image.setDeleteType("DELETE");
                list.add(image);
                
            } catch(IOException e) {
                log.error("Could not upload file " + mpf.getOriginalFilename(), e);
            }
            
        }
        
        Map<String, Object> files = new HashMap<String, Object>();
        files.put("files", list);
        return files;
    }
	
	@RequestMapping(value = "/picture/{id}", method = RequestMethod.GET)
    public void picture(HttpServletResponse response, @PathVariable Long id) {
        Image image = imageService.getImageById(id);
        String pathname = context.getRealPath(AppConstant.IMAGE_LOCATION);
        File imageFile = new File(pathname + "/"+ image.getNewFilename());
        response.setContentType(image.getContentType());
        response.setContentLength(image.getSize().intValue());
        try {
            InputStream is = new FileInputStream(imageFile);
            IOUtils.copy(is, response.getOutputStream());
        } catch(IOException e) {
            log.error("Could not show picture "+id, e);
        }
    }
    
    @RequestMapping(value = "/thumbnail/{id}", method = RequestMethod.GET)
    public void thumbnail(HttpServletResponse response, @PathVariable Long id) {
        Image image = imageService.getImageById(id);
        String pathname = context.getRealPath(AppConstant.IMAGE_LOCATION);
        File imageFile = new File(pathname + "/" + image.getThumbnailFilename());
        response.setContentType(image.getContentType());
        response.setContentLength(image.getThumbnailSize().intValue());
        if(imageFile.exists()){
	        try {
	            InputStream is = new FileInputStream(imageFile);
	            IOUtils.copy(is, response.getOutputStream());
	        } catch(IOException e) {
	            log.error("Could not show thumbnail "+id, e);
	        }
        }
    }
    
    @RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE)
    public @ResponseBody List<Map<String, Object>> delete(@PathVariable Long id) {
        Image image = imageService.getImageById(id);
        String pathname = context.getRealPath(AppConstant.IMAGE_LOCATION);
        File imageFile = new File(pathname + "/" + image.getNewFilename());
        imageFile.delete();
        File thumbnailFile = new File(pathname + "/" + image.getThumbnailFilename());
        thumbnailFile.delete();
        imageService.deleteImageById(image.getId());
        List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
        Map<String, Object> success = new HashMap<String, Object>();
        success.put("success", true);
        results.add(success);
        return results;
    }
}
